<?php


namespace App\Http\Model;

use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;

class TogetherGame extends Base
{
    protected $table = 'together_game';//游戏列表
    protected $togetherGameConfigTable = 'together_game_config';//游戏总开关设置
    protected $togetherGameSignConfigTable = 'together_game_sign_config';//一起玩签到配置
    protected $togetherGamePeopleStaticts = 'together_game_people_statistics';//每日游戏统计表
    protected $togetherGameUserSignLogTable = 'together_game_user_sign_log';//用户签到表
    protected $togetherGameNoticeTable = 'together_gamge_notice';//游戏公告
    protected $financeWallet = 'finance_wallet';//用户钱包
    protected $togethertGamePeopleConfigTable = 'together_game_people_config';//一起玩后台游戏配置列表
    protected $userModel;
    protected $mall_model;

    protected $togetherGameRedisList = 'TOGETHER:GAME:LIST';//string 一起玩游戏列表 TOGETHER:GAME:LIST=>{json}
    protected $togetherGameConfigRedis = 'TOGETHER:GAME:CONFIG';//string 一起玩游戏开关配置 TOGETHER:GAME:CONFIG=>{json}
    protected $togetherGameSignRedis = 'TOGETHER:GAME:SIGN';//string 一起玩签到缓存TOGETHER:GAME:SIGN
    protected $togetherGamePeopleListRedis = 'TOGETHER:GAME:PEOPLE:LIST';//hash 一起玩活动人数 TOGETHER:GAME:NAME:LIST => {game_name} => {count}
    protected $togetherGameNoticeRedis = 'TOGETHER:GAME:NOTICE';//string 一起玩游戏滚动公告TOGETHER:GAME:NOTICE => {json}

    protected $togethergameErrorDbLog = 'togetherGameErrorLog';

    public function __construct(array $attributes = [])
    {
        parent::__construct($this->table, $attributes);
        $this->userModel = new User();
        $this->mall_model = new Mall();
    }

    //处理数据 
    public function dataChange($params){
        try{
            DB::beginTransaction();
            if(!empty($params['id'])){
                $id = $params['id'];
                unset($params['id']);
                $params['updated_at'] = Carbon::now()->toDateTimeString();
                DB::table($this->table)->where('id',$id)->update($params);
            }else{
                unset($params['id']);
                $params['created_at'] = Carbon::now()->toDateTimeString();
                DB::table($this->table)->insert($params);
            }
            DB::commit();
            Redis::DEL($this->togetherGameRedisList);
            return true;
        }catch(\Exception $e){
            DB::rollBack();
            write_log($this->togethergameErrorDbLog,'ERROR 数据处理失败',['data'=>$params,'error'=>$e->getMessage(),'line'=>$e->getLine()]);
            return false;
        } 
    }

    //删除处理
    public function deleteGame($id){
        try{
            DB::beginTransaction();
            DB::table($this->table)->where('id',$id)->update(['is_deleted'=>1]);
            DB::commit();
            Redis::DEL($this->togetherGameRedisList);
            return true;
        }catch(\Exception $e){
            DB::rollBack();
            write_log($this->togethergameErrorDbLog,'ERROR 数据处理失败',['data'=>$id,'error'=>$e->getMessage(),'line'=>$e->getLine()]);
            return false;
        } 
    }

    //一起玩功能总开关
    public function setGameOpen($status, $diamond){
        try{
            DB::beginTransaction();
            //查询是否有数据
            $count = DB::table($this->togetherGameConfigTable)->count();
            $params = [
                'diamond' => $diamond,
                'status' => $status,
            ];
            if($count == 0){
                $params['created_at'] = Carbon::now()->toDateTimeString();
                DB::table($this->togetherGameConfigTable)->insert($params);
            }else{
                $params['updated_at'] = Carbon::now()->toDateTimeString();
                DB::table($this->togetherGameConfigTable)->where('id',1)->update($params);
            }
            Redis::DEL($this->togetherGameConfigRedis);
            DB::commit();
            return true;
        }catch(\Exception $e){
            DB::rollBack();
            write_log($this->togethergameErrorDbLog,'ERROR 更改总开关数据处理失败',['data'=>[$status,$diamond],'error'=>$e->getMessage(),'line'=>$e->getLine()]);
            return false;
        } 
    }

    //一起玩签到配置
    public function setDaySign($params){
        try{
            DB::beginTransaction();
            if(!empty($params['id'])){
                $id = $params['id'];
                unset($params['id']);
                $params['updated_at'] = Carbon::now()->toDateTimeString();
                DB::table($this->togetherGameSignConfigTable)->where('id',$id)->update($params);
            }else{
                unset($params['id']);
                $params['created_at'] = Carbon::now()->toDateTimeString();
                DB::table($this->togetherGameSignConfigTable)->insert($params);
            }
            DB::commit();
            Redis::DEL($this->togetherGameSignRedis);
            return true;
        }catch(\Exception $e){
            DB::rollBack();
            write_log($this->togethergameErrorDbLog,'ERROR 签到配置数据处理失败',['data'=>$params,'error'=>$e->getMessage(),'line'=>$e->getLine()]);
            return false;
        } 
    }

    //客户端-获取一起玩开关总配置
    public function getTogetherGameConfig(){
        $config = Redis::GET($this->togetherGameConfigRedis);
        if(!empty($config)){
            $config = json_decode($config,true);
            return $config;
        }
        $config = DB::table($this->togetherGameConfigTable)->where('status',1)->first();
        $config = objToArray($config);
        Redis::SET($this->togetherGameConfigRedis,json_encode($config));
        Redis::EXPIRE($this->togetherGameConfigRedis,7*86400);
        return $config;
    }

    //客户端-获取一起玩游戏列表
    public function getGameList(){
        $data = Redis::get($this->togetherGameRedisList);
        if(!empty($data)){
            $data = json_decode($data,true);
            return $data;
        }
        $data = DB::table($this->table)->where(['status'=>1,'is_deleted'=>0])->orderBy('sort','ASC')->orderBy('created_at','desc')->limit(10)->get();
        $data = objToArray($data);
        Redis::SET($this->togetherGameRedisList,json_encode($data));
        Redis::EXPIRE($this->togetherGameRedisList,7*86400);
        return $data;
    }

    //客户端--获取一起玩游戏游戏人数
    public function getYestorDayCount(){
        $todayStart = Carbon::today()->startOfDay()->toDateTimeString();
        $endDay = Carbon::today()->endOfDay()->toDateTimeString();
        $now = Carbon::now()->toDateTimeString();
        //脚本因为是0点02分执行所以缓存结束时间要延后两三分钟
        $afterEnd = Carbon::parse($endDay)->addMinutes(3);
        $diffTime = Carbon::parse($now)->diffInSeconds($afterEnd);
        
        $newData = Redis::HGETALL($this->togetherGamePeopleListRedis);
        if(empty($newData)){
            $data = DB::table($this->togetherGamePeopleStaticts)->where('created_at','>=',$todayStart)->where('created_at','<=',$endDay)->get();
            $data = objToArray($data);
            if(empty($data)){
                return [];
            }
            //获取用户头像
            $data = array_column($data,null,'game_name');
            $newData = [];
            foreach($data as $v){
                if(empty($v['join_users'])){
                    $joindata = [
                        'nums' => 0,
                        'peopleImg' => []
                    ];
                    $newData[$v['game_name']] = json_encode($joindata);
                }else{
                    $userIdArr = explode(',',$v['join_users']);
                    foreach($userIdArr as $value){
                        $userInfo = $this->userModel->get_user($value);
                        $peopleImg[] = isset($userInfo['images'][0]) && $userInfo['images'][0] ? $userInfo['images'][0].'?x-oss-process=image/resize,w_60,m_lfit' : build_image('/portrait/atm.png');
                    }
                    $joindata = [
                        'nums' => $v['people_count'],
                        'peopleImg' => $peopleImg
                    ];
                    $newData[$v['game_name']] = json_encode($joindata);   
                }
                unset($peopleImg);
            }
            Redis::HMSET($this->togetherGamePeopleListRedis,$newData);
            Redis::EXPIRE($this->togetherGamePeopleListRedis,$diffTime);
        }
        return $newData;
    }

    //客户端-获取签到列表
    public function getSignList(){
        $list = Redis::GET($this->togetherGameSignRedis);
        if(!empty($list)){
            return json_decode($list,true);
        }
        $list = DB::table($this->togetherGameSignConfigTable)->where('status',1)->orderBy('sigin_day','ASC')->get();
        $list = objToArray($list);
        Redis::SET($this->togetherGameSignRedis,json_encode($list));
        Redis::EXPIRE($this->togetherGameSignRedis,7*86400);
        return $list;
    }

    //查看用户是否连续签到
    public function getSignTimes($userId){
        //获取用户最近一条签到记录
        $beforeSign = DB::table($this->togetherGameUserSignLogTable)->where('user_id',$userId)->orderBy('last_time','DESC')->first();
        $beforeSign = objToArray($beforeSign);
        if(!empty($beforeSign)){
            //判断签到天数是否大于1天
            $now = Carbon::now()->toDateTimeString();
            $diffDay = Carbon::parse($now)->diffInDays($beforeSign['last_time']);
            if($diffDay > 1){
                return 0;
            }
            return 1;
        }
        return 0;
    }

    //查看用户是否签到过对应天数
    public function checkIssetSign($userId, $signId){
        $check = DB::table($this->togetherGameUserSignLogTable)->where('user_id',$userId)->where('sign_id',$signId)->exists();
        return $check;
    }

    //客户端-查看今日是否签到过
    public function checkTodaySign($userId){
        $todayStart = Carbon::today()->startOfDay()->toDateTimeString();
        $todayEnd = Carbon::today()->endOfDay()->toDateTimeString();
        $check = DB::table($this->togetherGameUserSignLogTable)->where('user_id',$userId)->where('created_at','>=',$todayStart)->where('created_at','<=',$todayEnd)->exists();
        return $check;
    }

    //客户端-签到
    public function setTodaySign($userId,$signId){
        //查看签到奖励
        $signInfo = $this->getSignList();
        $signInfo = array_column($signInfo,null,'id');
        $signInfo = $signInfo[$signId];
        //入库签到
        $params = [
            'user_id' => $userId,
            'sign_day' => $signInfo['sigin_day'],//签到天
            'sign_id' => $signId,
            'last_time' => Carbon::now()->toDateTimeString(),
            'created_at' => Carbon::now()->toDateTimeString()
        ];
        $msg = '';
        try{
            DB::beginTransaction();
            $status = DB::table($this->togetherGameUserSignLogTable)->insert($params);
            if($status){
                if($signInfo['send_type'] == 1){
                    //娱乐积分
                    DB::table($this->financeWallet)->where('user_id', '=', $userId)
                    ->increment('game_balance', $signInfo['send_num'], ['change_timestamp'=> time()]);
                    $msg = '恭喜您获得'.$signInfo['send_num'].'娱乐等级积分~';
                }elseif($signInfo['send_type'] == 2){
                    //金豆
                    DB::table($this->financeWallet)
                        ->where('user_id', '=', $userId)
                        ->increment('jd_balance', $signInfo['send_num'], ['change_timestamp'=> time()]);
                    $msg = '恭喜您获得'.$signInfo['send_num'].'个金豆,已为您自动下发~';
                }elseif($signInfo['send_type'] == 3){
                    //礼物
                    //发放头像,气泡
                    $goodInfo = $this->mall_model->getMallGoodByGoodsId($signInfo['send_id']);
                    $skuList = $this->mall_model->getSkuDataByGoods($signInfo['send_id']);
                    $timeLimit = $signInfo['send_num']*86400;
                    $this->mall_model->shoppingAct(
                        11,
                        $userId,
                        $goodInfo['goods_id'],
                        $goodInfo['goods_name'],
                        $goodInfo['goods_type'],
                        $skuList[0]['sku_id'],
                        $timeLimit,
                        0,
                        $timeLimit,
                        time(),
                        2
                    );
                    $msg = '恭喜您获得'.$goodInfo['goods_name'].'*'.$signInfo['send_num'].'天,已为您自动下发到我的装扮~';
                }
            }
            DB::commit();
            return $msg;
        }catch(\Exception $e){
            DB::rollBack();
            write_log($this->togetherGameSignError,'ERROR 签到失败',['data'=>$params,'msg'=>$e->getMessage(),'line'=>$e->getLine()]);
            return $msg;
        }
    }

    //获取游戏滚动公告
    public function getGameNotice(){
        $data = Redis::get($this->togetherGameNoticeRedis);
        if(!empty($data)){
            $data = json_decode($data,true);
        }else{
            $data = DB::table($this->togetherGameNoticeTable)->limit(20)->orderBy('created_at','DESC')->get();
            $data = objToArray($data);
            Redis::SET($this->togetherGameNoticeRedis,json_encode($data));
            Redis::EXPIRE($this->togetherGameNoticeRedis,120);
        }
        return $data;
    }

    //获取游戏名称列表
    public function getGameNameList(){
        $data = DB::table($this->togethertGamePeopleConfigTable)->get();
        $data = objToArray($data);
        return $data;
    }
}